﻿//Copyright (c) 2012 NextGen Systems UK

//Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), 
//to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 
//and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
//WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Collections.Specialized;
using System.Xml;
using System.Xml.Linq;

namespace NextGenSystems.WHMCS
{
    public class API
    {
        private string installurl { get; set; }
        private string username { get; set; }
        private string password { get; set; }
        private string accesskey { get; set; }

        public API(string Username, string Password, string Installurl, string AccessKey)
        {
            username = Username;
            password = MD5Core.GetHashString(Password);
            installurl = Installurl;
            accesskey = AccessKey;

        }

        #region Validate Login

        public string ValidateLogin(string email, string userpass)
        {
            WebClient WHMCSclient = new WebClient();

            // Prepare a Name/Value collection to hold the post values
            NameValueCollection form = new NameValueCollection();
            form.Add("accesskey", accesskey);
            form.Add("username", username);
            form.Add("password", password); // the password will still need encoding is MD5 is a requirement
            form.Add("action", "validatelogin"); // action performed by the API:Functions
            form.Add("responsetype", "xml");

            form.Add("email", email);
            form.Add("password2", userpass);

            // Post the data and read the response
            Byte[] responseData = WHMCSclient.UploadValues(installurl, form);

            // Decode and display the response.

            string xmlstring = Encoding.ASCII.GetString(responseData);
            XDocument mydoc = XDocument.Parse(xmlstring);

            string result = string.Empty;
            try
            {
                var Details = (from x in mydoc.Elements("whmcsapi")
                               select new { UserId = x.Element("userid").Value, 
                                   Result = x.Element("result").Value }).FirstOrDefault();

                if (Details.Result == "success")
                    result = Details.UserId;
            }
            catch (Exception ex)
            {
              
            }

            return result;
        }

        #endregion

        #region GetClient

        public string GetClientsXML(int limitstart = 0, int limitnum = 0, string search = "")
        {
            // Instantiate the WebClient object
            WebClient WHMCSclient = new WebClient();

            // Prepare a Name/Value collection to hold the post values
            NameValueCollection form = new NameValueCollection();
            form.Add("accesskey", accesskey);
            form.Add("username", username);
            form.Add("password", password); // the password will still need encoding is MD5 is a requirement
            form.Add("action", "getclients"); // action performed by the API:Functions
            form.Add("responsetype", "xml");
            if (limitstart != 0)
            {
                form.Add("limitstart", limitstart.ToString());
            }
            if (limitnum != 0)
            {
                form.Add("limitnum", limitnum.ToString());
            }
            if (search != "")
            {
                form.Add("search", search);
            }

            // Post the data and read the response
            Byte[] responseData = WHMCSclient.UploadValues(installurl, form);

            // Decode and display the response.
            return Encoding.ASCII.GetString(responseData);

        }

        public GetClientsRS GetClients(int limitstart = 0, int limitnum = 0, string search = "")
        {
            // Instantiate the WebClient object
            WebClient WHMCSclient = new WebClient();

            // Prepare a Name/Value collection to hold the post values
            NameValueCollection form = new NameValueCollection();
            form.Add("accesskey", accesskey);
            form.Add("username", username);
            form.Add("password", password); // the password will still need encoding is MD5 is a requirement
            form.Add("action", "getclients"); // action performed by the API:Functions
            form.Add("responsetype", "xml");
            if (limitstart != 0)
            {
                form.Add("limitstart", limitstart.ToString());
            }
            if (limitnum != 0)
            {
                form.Add("limitnum", limitnum.ToString());
            }
            if (search != "")
            {
                form.Add("search", search);
            }


            // Post the data and read the response
            Byte[] responseData = WHMCSclient.UploadValues(installurl, form);

            // Decode and display the response.
            string xmlstring = Encoding.ASCII.GetString(responseData);
            XDocument mydoc = XDocument.Parse(xmlstring);

            GetClientsRS Result = new GetClientsRS();
            List<Client> clientlist = new List<Client>();

            try
            {
                var Details = (from x in mydoc.Elements("whmcsapi")
                               select new { Action = x.Element("action").Value, Result = x.Element("result").Value }).FirstOrDefault();

                Result.Result = Details.Result;
                Result.Action = Details.Action;


                IEnumerable<XElement> xmlclients = (from x in mydoc.Descendants("client")
                                                    select x);
                if (Result.Result == "success")
                {
                    var Details2 = (from x in mydoc.Elements("whmcsapi")
                                    select new { totalresults = x.Element("totalresults").Value, startnumber = x.Element("startnumber").Value, numreturned = x.Element("numreturned").Value }).FirstOrDefault();
                    Result.TotalResults = Convert.ToInt32(Details2.totalresults);
                    Result.StartNumber = Convert.ToInt32(Details2.startnumber);
                    Result.NumReturned = Convert.ToInt32(Details2.numreturned);

                    foreach (XElement x in xmlclients)
                    {
                        Client gcr = new Client();
                        gcr.Lastname = x.Element("lastname").Value;
                        gcr.Firstname = x.Element("firstname").Value;
                        gcr.Companyname = x.Element("companyname").Value;
                        gcr.Email = x.Element("email").Value;
                        clientlist.Add(gcr);
                    }
                }
                else
                {
                    Result.ErrorMessage = (from x in mydoc.Elements("whmcsapi")
                                           select x.Element("message").Value).FirstOrDefault();
                }
            }
            catch (Exception ex)
            {
                Result.Result = "error";
                Result.ErrorMessage = ex.Message.ToString();
            }

            Result.Clients = clientlist;
            return Result;

        }

        #endregion

        #region GetCelitnDetails

        public string GetClientDetailsXML(Int64 clientid, string email = "")
        {

            // Instantiate the WebClient object
            WebClient WHMCSclient = new WebClient();

            // Prepare a Name/Value collection to hold the post values
            NameValueCollection form = new NameValueCollection();
            form.Add("accesskey", accesskey);
            form.Add("username", username);
            form.Add("password", password); // the password will still need encoding is MD5 is a requirement
            form.Add("action", "getclientsdetails"); // action performed by the API:Functions
            form.Add("responsetype", "xml");
            if (clientid != 0)
            {
                form.Add("clientid", clientid.ToString());
            }
            if (email != "")
            {
                form.Add("email", email);
            }

            // Post the data and read the response
            Byte[] responseData = WHMCSclient.UploadValues(installurl, form);

            // Decode and display the response.
            return Encoding.ASCII.GetString(responseData);
        }

        public GetClinetDetailsRS GetClientDetails(Int64 clientid, string email = "")
        {
            // Instantiate the WebClient object
            WebClient WHMCSclient = new WebClient();

            // Prepare a Name/Value collection to hold the post values
            NameValueCollection form = new NameValueCollection();
            form.Add("accesskey", accesskey);
            form.Add("username", username);
            form.Add("password", password); // the password will still need encoding is MD5 is a requirement
            form.Add("action", "getclientsdetails"); // action performed by the API:Functions
            form.Add("responsetype", "xml");
            if (clientid != 0)
            {
                form.Add("clientid", clientid.ToString());
            }
            if (email != "")
            {
                form.Add("email", email);
            }


            // Post the data and read the response
            Byte[] responseData = WHMCSclient.UploadValues(installurl, form);

            // Decode and display the response.
            string xmlstring = Encoding.ASCII.GetString(responseData);
            XDocument mydoc = XDocument.Parse(xmlstring);

            GetClinetDetailsRS Result = new GetClinetDetailsRS();
            List<ClinetDetails> clientdetailslist = new List<ClinetDetails>();
            ClinetDetails gcr = null;
            try
            {
                var Details = (from x in mydoc.Elements("whmcsapi")
                               select new { Action = x.Element("action").Value, Result = x.Element("result").Value }).FirstOrDefault();

                Result.Result = Details.Result;
                Result.Action = Details.Action;


                IEnumerable<XElement> xmlclients = (from x in mydoc.Descendants("client")
                                                    select x);
                if (Result.Result == "success")
                {
                    //var Details2 = (from x in mydoc.Elements("whmcsapi")
                    //                select new { totalresults = x.Element("totalresults").Value, startnumber = x.Element("startnumber").Value, numreturned = x.Element("numreturned").Value }).FirstOrDefault();
                    //Result.TotalResults = Convert.ToInt32(Details2.totalresults);
                    //Result.StartNumber = Convert.ToInt32(Details2.startnumber);
                    //Result.NumReturned = Convert.ToInt32(Details2.numreturned);

                    foreach (XElement x in xmlclients)
                    {
                        gcr = new ClinetDetails();

                        gcr.Id = int.Parse(x.Element("id").Value);
                        gcr.Firstname = x.Element("firstname").Value;
                        gcr.Lastname = x.Element("lastname").Value;
                        gcr.Companyname = x.Element("companyname").Value;
                        gcr.Email = x.Element("email").Value;
                        gcr.Address1 = x.Element("address1").Value;
                        gcr.Address2 = x.Element("address2").Value;
                        gcr.City = x.Element("city").Value;
                        gcr.State = x.Element("state").Value;
                        gcr.Postcode = x.Element("postcode").Value;
                        gcr.Country = x.Element("country").Value;
                        gcr.Countryname = x.Element("countryname").Value;
                        gcr.Phonenumber = x.Element("phonenumber").Value;
                        gcr.Notes = x.Element("notes").Value;
                        gcr.Password = x.Element("password").Value;
                        gcr.Currency = x.Element("currency").Value;
                        gcr.Securityqid = x.Element("securityqid").Value;
                        gcr.Securityqans = x.Element("securityqans").Value;
                        gcr.Groupid = x.Element("groupid").Value;
                        gcr.Status = x.Element("status").Value;
                        gcr.Credit = Decimal.Parse(x.Element("credit").Value);
                        gcr.Taxexempt = x.Element("taxexempt").Value;
                        gcr.Latefeeoveride = x.Element("latefeeoveride").Value;
                        gcr.Overideduenotices = x.Element("overideduenotices").Value;
                        gcr.Language = x.Element("language").Value;
                        gcr.Lastlogin = x.Element("lastlogin").Value;
                        gcr.Billingcid = int.Parse(x.Element("billingcid").Value);

                        Result.ClientDetails = gcr;
                    }
                }
                else
                {
                    Result.ErrorMessage = (from x in mydoc.Elements("whmcsapi")
                                           select x.Element("message").Value).FirstOrDefault();
                }
            }
            catch (Exception ex)
            {
                Result.Result = "error";
                Result.ErrorMessage = ex.Message.ToString();
            }

            return Result;
        }

        #endregion

        #region Invoice

        public string GetInvoiceXML(int invoiceid = 0)
        {

            // Instantiate the WebClient object
            WebClient WHMCSclient = new WebClient();

            // Prepare a Name/Value collection to hold the post values
            NameValueCollection form = new NameValueCollection();
            form.Add("accesskey", accesskey);
            form.Add("username", username);
            form.Add("password", password); // the password will still need encoding is MD5 is a requirement
            form.Add("action", "getinvoice"); // action performed by the API:Functions
            form.Add("responsetype", "xml");
            if (invoiceid != 0)
            {
                form.Add("invoiceid", invoiceid.ToString());
            }


            // Post the data and read the response
            Byte[] responseData = WHMCSclient.UploadValues(installurl, form);

            // Decode and display the response.
            return Encoding.ASCII.GetString(responseData);
        }

        public GetInvoiceRS GetInvoice(int invoiceid = 0)
        {
            // Instantiate the WebClient object
            WebClient WHMCSclient = new WebClient();

            // Prepare a Name/Value collection to hold the post values
            NameValueCollection form = new NameValueCollection();
            form.Add("accesskey", accesskey);
            form.Add("username", username);
            form.Add("password", password); // the password will still need encoding is MD5 is a requirement
            form.Add("action", "getinvoice"); // action performed by the API:Functions
            form.Add("responsetype", "xml");
            if (invoiceid != 0)
            {
                form.Add("invoiceid", invoiceid.ToString());
            }

            // Post the data and read the response
            Byte[] responseData = WHMCSclient.UploadValues(installurl, form);

            // Decode and display the response.
            string xmlstring = Encoding.ASCII.GetString(responseData);
            XDocument mydoc = XDocument.Parse(xmlstring);

            GetInvoiceRS Result = new GetInvoiceRS();
            List<Invoice> InvoiceDetailsList = new List<Invoice>();
            Invoice inv = null;
            Item itm = null;

            try
            {
                var Details = (from x in mydoc.Elements("whmcsapi")
                               select new { Action = x.Element("action").Value, Result = x.Element("result").Value }).FirstOrDefault();

                Result.Result = Details.Result;
                Result.Action = Details.Action;


                IEnumerable<XElement> xmlinv = (from x in mydoc.Descendants("whmcsapi")
                                                select x);
                if (Result.Result == "success")
                {
                    foreach (XElement x in xmlinv)
                    {
                        inv = new Invoice();
                        inv.Items = new List<Item>();
                        inv.Invoiceid = x.Element("invoiceid").Value;
                        inv.Invoicenum = x.Element("invoicenum").Value;
                        inv.Userid = x.Element("userid").Value;
                        inv.Date = x.Element("date").Value;
                        inv.Duedate = x.Element("duedate").Value;
                        inv.Datepaid = x.Element("datepaid").Value;
                        inv.Subtotal = x.Element("subtotal").Value;
                        inv.Credit =x.Element("credit").Value;
                        inv.Tax = x.Element("tax").Value;
                        inv.Tax2 = x.Element("tax2").Value;
                        inv.Total = x.Element("total").Value;
                        inv.Taxrate = x.Element("taxrate").Value;
                        inv.Taxrate2 = x.Element("taxrate2").Value;
                        inv.Status = x.Element("status").Value;
                        inv.Paymentmethod = x.Element("paymentmethod").Value;
                        inv.Notes = x.Element("notes").Value;
                        inv.Transactions = x.Element("transactions").Value;

                        IEnumerable<XElement> xmlitm = (from i in mydoc.Descendants("item")
                                                        select i);

                        foreach (XElement i in xmlitm)
                        {
                            itm = new Item();
                            itm.Id = i.Element("id").Value;
                            itm.Type = i.Element("type").Value;
                            itm.Relid = i.Element("relid").Value;
                            itm.Description = i.Element("description").Value; 
                            itm.Amount = i.Element("amount").Value;
                            itm.Taxed = i.Element("taxed").Value;
                            inv.Items.Add(itm);
                        }
                        InvoiceDetailsList.Add(inv);
                    }
                }
                else
                {
                    Result.ErrorMessage = (from x in mydoc.Elements("whmcsapi")
                                           select x.Element("message").Value).FirstOrDefault();
                }
            }
            catch (Exception ex)
            {
                Result.Result = "error";
                Result.ErrorMessage = ex.Message.ToString();
            }

            Result.Invoice = InvoiceDetailsList;
            return Result;
        }

        public string GetInvoicesXML(int userid = 0, string status = "", int limitstart = 0, int limitnum = 0)
        {

            // Instantiate the WebClient object
            WebClient WHMCSclient = new WebClient();

            // Prepare a Name/Value collection to hold the post values
            NameValueCollection form = new NameValueCollection();
            form.Add("accesskey", accesskey);
            form.Add("username", username);
            form.Add("password", password); // the password will still need encoding is MD5 is a requirement
            form.Add("action", "getinvoices"); // action performed by the API:Functions
            form.Add("responsetype", "xml");

            if (userid != 0)
            {
                form.Add("userid", userid.ToString());
            }
            if (status != "")
            {
                form.Add("status", status);
            }
            if (limitstart != 0)
            {
                form.Add("limitstart", limitstart.ToString());
            }
            if (limitnum != 0)
            {
                form.Add("limitnum", limitnum.ToString());
            }


            // Post the data and read the response
            Byte[] responseData = WHMCSclient.UploadValues(installurl, form);

            // Decode and display the response.
            return Encoding.ASCII.GetString(responseData);
        }

        public GetInvoicesRS GetInvoices(int userid = 0, string status = "", int limitstart = 0, int limitnum = 0)
        {
            // Instantiate the WebClient object
            WebClient WHMCSclient = new WebClient();

            // Prepare a Name/Value collection to hold the post values
            NameValueCollection form = new NameValueCollection();
            form.Add("accesskey", accesskey);
            form.Add("username", username);
            form.Add("password", password); // the password will still need encoding is MD5 is a requirement
            form.Add("action", "getinvoices"); // action performed by the API:Functions
            form.Add("responsetype", "xml");

            if (userid != 0)
            {
                form.Add("userid", userid.ToString());
            }
            if (status != "")
            {
                form.Add("status", status);
            }
            if (limitstart != 0)
            {
                form.Add("limitstart", limitstart.ToString());
            }
            if (limitnum != 0)
            {
                form.Add("limitnum", limitnum.ToString());
            }


            // Post the data and read the response
            Byte[] responseData = WHMCSclient.UploadValues(installurl, form);

            // Decode and display the response.
            string xmlstring = Encoding.ASCII.GetString(responseData);
            XDocument mydoc = XDocument.Parse(xmlstring);

            GetInvoicesRS Result = new GetInvoicesRS();
            List<Invoices> InvoiceDetailsList = new List<Invoices>();

            try
            {
                var Details = (from x in mydoc.Elements("whmcsapi")
                               select new { Action = x.Element("action").Value, Result = x.Element("result").Value }).FirstOrDefault();

                Result.Result = Details.Result;
                Result.Action = Details.Action;


                IEnumerable<XElement> xmlclients = (from x in mydoc.Descendants("invoice")
                                                    select x);
                if (Result.Result == "success")
                {
                    var Details2 = (from x in mydoc.Elements("whmcsapi")
                                    select new { totalresults = x.Element("totalresults").Value, startnumber = x.Element("startnumber").Value, numreturned = x.Element("numreturned").Value }).FirstOrDefault();
                    Result.TotalResults = Convert.ToInt32(Details2.totalresults);
                    Result.StartNumber = Convert.ToInt32(Details2.startnumber);
                    Result.NumReturned = Convert.ToInt32(Details2.numreturned);

                    foreach (XElement x in xmlclients)
                    {
                        Invoices inv = new Invoices();
                        inv.Id = x.Element("id").Value;
                        inv.Invoicenum = x.Element("invoicenum").Value;
                        inv.Userid = x.Element("userid").Value;
                        inv.Date = x.Element("date").Value;
                        inv.Duedate = x.Element("duedate").Value;
                        inv.Datepaid = x.Element("datepaid").Value;
                        inv.Subtotal = x.Element("subtotal").Value;
                        inv.Credit = x.Element("credit").Value;
                        inv.Tax = x.Element("tax").Value;
                        inv.Tax2 =x.Element("tax2").Value;
                        inv.Total = x.Element("total").Value;
                        inv.Taxrate = x.Element("taxrate").Value;
                        inv.Taxrate2 =x.Element("taxrate2").Value;
                        inv.Status = x.Element("status").Value;
                        inv.Paymentmethod = x.Element("paymentmethod").Value;
                        inv.Notes = x.Element("notes").Value;
                        InvoiceDetailsList.Add(inv);
                    }
                }
                else
                {
                    Result.ErrorMessage = (from x in mydoc.Elements("whmcsapi")
                                           select x.Element("message").Value).FirstOrDefault();
                }
            }
            catch (Exception ex)
            {
                Result.Result = "error";
                Result.ErrorMessage = ex.Message.ToString();
            }

            Result.Invoices = InvoiceDetailsList;
            return Result;
        }

        #endregion

        #region Transactions

        public string GetTransactionsXML(int clientid = 0, int invoiceid = 0, int transid = 0)
        {

            // Instantiate the WebClient object
            WebClient WHMCSclient = new WebClient();

            // Prepare a Name/Value collection to hold the post values
            NameValueCollection form = new NameValueCollection();
            form.Add("accesskey", accesskey);
            form.Add("username", username);
            form.Add("password", password); // the password will still need encoding is MD5 is a requirement
            form.Add("action", "gettransactions"); // action performed by the API:Functions
            form.Add("responsetype", "xml");

            if (clientid != 0)
            {
                form.Add("clientid", clientid.ToString());
            }
            if (invoiceid != 0)
            {
                form.Add("invoiceid", invoiceid.ToString());
            }
            if (transid != 0)
            {
                form.Add("transid", transid.ToString());
            }

            // Post the data and read the response
            Byte[] responseData = WHMCSclient.UploadValues(installurl, form);

            // Decode and display the response.
            return Encoding.ASCII.GetString(responseData);
        }

        public GetTransactionsRS GetTransations(int clientid = 0, int invoiceid = 0, int transid = 0)
        {
            // Instantiate the WebClient object
            WebClient WHMCSclient = new WebClient();

            // Prepare a Name/Value collection to hold the post values
            NameValueCollection form = new NameValueCollection();
            form.Add("accesskey", accesskey);
            form.Add("username", username);
            form.Add("password", password); // the password will still need encoding is MD5 is a requirement
            form.Add("action", "gettransactions"); // action performed by the API:Functions
            form.Add("responsetype", "xml");

            if (clientid != 0)
            {
                form.Add("clientid", clientid.ToString());
            }
            if (invoiceid != 0)
            {
                form.Add("invoiceid", invoiceid.ToString());
            }
            if (transid != 0)
            {
                form.Add("transid", transid.ToString());
            }


            // Post the data and read the response
            Byte[] responseData = WHMCSclient.UploadValues(installurl, form);

            // Decode and display the response.
            string xmlstring = Encoding.ASCII.GetString(responseData);
            XDocument mydoc = XDocument.Parse(xmlstring);

            GetTransactionsRS Result = new GetTransactionsRS();
            List<Transactions> transactions = new List<Transactions>();
            Transactions gt = null;

            try
            {
                var Details = (from x in mydoc.Elements("whmcsapi")
                               select new { Action = x.Element("action").Value, Result = x.Element("result").Value }).FirstOrDefault();

                Result.Result = Details.Result;
                Result.Action = Details.Action;

                IEnumerable<XElement> xmlclients = (from x in mydoc.Descendants("transaction")
                                                    select x);
                if (Result.Result == "success")
                {
                    var Details2 = (from x in mydoc.Elements("whmcsapi")
                                    select new { totalresults = x.Element("totalresults").Value, startnumber = x.Element("startnumber").Value, numreturned = x.Element("numreturned").Value }).FirstOrDefault();
                    Result.TotalResults = Convert.ToInt32(Details2.totalresults);
                    Result.StartNumber = Convert.ToInt32(Details2.startnumber);
                    Result.NumReturned = Convert.ToInt32(Details2.numreturned);

                    foreach (XElement x in xmlclients)
                    {
                        gt = new Transactions();

                        gt.Id = x.Element("id").Value;
                        gt.Userid = x.Element("userid").Value;
                        gt.Currency = x.Element("currency").Value;
                        gt.Gateway = x.Element("gateway").Value;
                        gt.Date = x.Element("date").Value;
                        gt.Description = x.Element("description").Value;
                        gt.Amountin = x.Element("amountin").Value;
                        gt.Fees = x.Element("fees").Value;
                        gt.Amountout = x.Element("amountout").Value;
                        gt.Rate = x.Element("rate").Value;
                        gt.Transid = x.Element("transid").Value;
                        gt.Invoiceid = x.Element("invoiceid").Value;
                        gt.Refundid = x.Element("refundid").Value;

                        transactions.Add(gt);
                    }
                }
                else
                {
                    Result.ErrorMessage = (from x in mydoc.Elements("whmcsapi")
                                           select x.Element("message").Value).FirstOrDefault();
                }
            }
            catch (Exception ex)
            {
                Result.Result = "error";
                Result.ErrorMessage = ex.Message.ToString();
            }

            Result.TransactionsDetails = transactions;
            return Result;
        }

        #endregion

        #region Get Tickets

        public string GetTicketXML()
        {

            // Instantiate the WebClient object
            WebClient WHMCSclient = new WebClient();

            // Prepare a Name/Value collection to hold the post values
            NameValueCollection form = new NameValueCollection();
            form.Add("accesskey", accesskey);
            form.Add("username", username);
            form.Add("password", password); // the password will still need encoding is MD5 is a requirement
            form.Add("action", "getticket"); // action performed by the API:Functions
            form.Add("responsetype", "xml");


            // Post the data and read the response
            Byte[] responseData = WHMCSclient.UploadValues(installurl, form);

            // Decode and display the response.
            return Encoding.ASCII.GetString(responseData);
        }

        public GetTicketRS GetTicket(int ticketid=0)
        {
            // Instantiate the WebClient object
            WebClient WHMCSclient = new WebClient();

            // Prepare a Name/Value collection to hold the post values
            NameValueCollection form = new NameValueCollection();
            form.Add("accesskey", accesskey);
            form.Add("username", username);
            form.Add("password", password); // the password will still need encoding is MD5 is a requirement
            form.Add("action", "getticket"); // action performed by the API:Functions
            form.Add("responsetype", "xml");

            form.Add("ticketid", ticketid.ToString());

            // Post the data and read the response
            Byte[] responseData = WHMCSclient.UploadValues(installurl, form);

            // Decode and display the response.
            string xmlstring = Encoding.ASCII.GetString(responseData);
            XDocument mydoc = XDocument.Parse(xmlstring);

            GetTicketRS Result = new GetTicketRS();
            List<Ticket> ticketDetailsList = new List<Ticket>();
            Ticket tck = null;
            Reply rply = null;


            try
            {
                var Details = (from x in mydoc.Elements("whmcsapi")
                               select new { Action = x.Element("action").Value, Result = x.Element("result").Value }).FirstOrDefault();

                Result.Result = Details.Result;
                Result.Action = Details.Action;


                IEnumerable<XElement> xmlclients = (from x in mydoc.Descendants("whmcsapi")
                                                    select x);
                if (Result.Result == "success")
                {
                    //var Details2 = (from x in mydoc.Elements("whmcsapi")
                    //                select new { totalresults = x.Element("totalresults").Value, startnumber = x.Element("startnumber").Value, numreturned = x.Element("numreturned").Value }).FirstOrDefault();
                    //Result.TotalResults = Convert.ToInt32(Details2.totalresults);
                    //Result.StartNumber = Convert.ToInt32(Details2.startnumber);
                    //Result.NumReturned = Convert.ToInt32(Details2.numreturned);

                    foreach (XElement x in xmlclients)
                    {
                        tck = new Ticket();

                        tck.Id = x.Element("ticketid").Value;
                        tck.Tid = x.Element("tid").Value;
                        tck.Deptid =x.Element("deptid").Value;
                        tck.Userid = x.Element("userid").Value;
                        tck.Name = x.Element("name").Value;
                        tck.Email = x.Element("email").Value;
                        tck.Cc = x.Element("cc").Value;
                        tck.C = x.Element("c").Value;
                        tck.Date = x.Element("date").Value;
                        tck.Subject = x.Element("subject").Value;
                      //  tck.Message = x.Element("message").Value;
                        tck.Status = x.Element("status").Value;
                        tck.Priority = x.Element("priority").Value;
                        tck.Admin = x.Element("admin").Value;
                    //    tck.Attachment = x.Element("attachment").Value;
                        tck.Lastreply = x.Element("lastreply").Value;
                        tck.Flag = x.Element("flag").Value;
                        tck.Service = x.Element("service").Value;

                        IEnumerable<XElement> xmlrply = (from i in mydoc.Descendants("reply")
                                                         select i);

                        tck.Reply = new List<Reply>();
                        foreach (XElement i in xmlrply)
                        {
                            rply = new Reply();
                            rply.Userid = i.Element("userid").Value;
                            rply.Name = i.Element("name").Value;
                            rply.Email = i.Element("email").Value;
                            rply.Date = i.Element("date").Value;
                            rply.Message = i.Element("message").Value;
                            rply.Attachment = i.Element("attachment").Value;
                            rply.Admin = i.Element("admin").Value;

                            tck.Reply.Add(rply);
                        }

                        ticketDetailsList.Add(tck);
                    }
                }
                else
                {
                    Result.ErrorMessage = (from x in mydoc.Elements("whmcsapi")
                                           select x.Element("message").Value).FirstOrDefault();
                }
            }
            catch (Exception ex)
            {
                Result.Result = "error";
                Result.ErrorMessage = ex.Message.ToString();
            }

            Result.Ticket = ticketDetailsList;
            return Result;
        }

        public string GetTicketsXML(int limitstart = 0, int limitnum = 0, int clientid = 0, int deptid = 0, string status = "", string subject = "", string ignore_dept_assignments = "")
        {

            // Instantiate the WebClient object
            WebClient WHMCSclient = new WebClient();

            // Prepare a Name/Value collection to hold the post values
            NameValueCollection form = new NameValueCollection();
            form.Add("accesskey", accesskey);
            form.Add("username", username);
            form.Add("password", password); // the password will still need encoding is MD5 is a requirement
            form.Add("action", "gettickets"); // action performed by the API:Functions
            form.Add("responsetype", "xml");

            if (limitstart != 0)
            {
                form.Add("limitstart", limitstart.ToString());
            }
            if (limitnum != 0)
            {
                form.Add("limitnum", limitnum.ToString());
            }
            if (clientid != 0)
            {
                form.Add("clientid", clientid.ToString());
            }
            if (deptid != 0)
            {
                form.Add("deptid", deptid.ToString());
            }
            if (status != "")
            {
                form.Add("status", status);
            }
            if (subject != "")
            {
                form.Add("subject", subject);
            }
            if (ignore_dept_assignments != "")
            {
                form.Add("ignore_dept_assignments", ignore_dept_assignments);
            }
            // Post the data and read the response
            Byte[] responseData = WHMCSclient.UploadValues(installurl, form);

            // Decode and display the response.
            return Encoding.ASCII.GetString(responseData);
        }

        public GetTicketRS GetTickets(int limitstart = 0, int limitnum = 0, int clientid = 0, int deptid = 0, string status = "", string subject = "", string ignore_dept_assignments = "")
        {
            // Instantiate the WebClient object
            WebClient WHMCSclient = new WebClient();

            // Prepare a Name/Value collection to hold the post values
            NameValueCollection form = new NameValueCollection();
            form.Add("accesskey", accesskey);
            form.Add("username", username);
            form.Add("password", password); // the password will still need encoding is MD5 is a requirement
            form.Add("action", "gettickets"); // action performed by the API:Functions
            form.Add("responsetype", "xml");

            if (limitstart != 0)
            {
                form.Add("limitstart", limitstart.ToString());
            }
            if (limitnum != 0)
            {
                form.Add("limitnum", limitnum.ToString());
            }
            if (clientid != 0)
            {
                form.Add("clientid", clientid.ToString());
            }
            if (deptid != 0)
            {
                form.Add("deptid", deptid.ToString());
            }
            if (status != "")
            {
                form.Add("status", status);
            }
            if (subject != "")
            {
                form.Add("subject", subject);
            }
            if (ignore_dept_assignments != "")
            {
                form.Add("ignore_dept_assignments", ignore_dept_assignments);
            }
            // Post the data and read the response
            Byte[] responseData = WHMCSclient.UploadValues(installurl, form);

            // Decode and display the response.
            string xmlstring = Encoding.ASCII.GetString(responseData);
            XDocument mydoc = XDocument.Parse(xmlstring);

            GetTicketRS Result = new GetTicketRS();
            List<Ticket> ticketDetailsList = new List<Ticket>();

            try
            {
                var Details = (from x in mydoc.Elements("whmcsapi")
                               select new { Action = x.Element("action").Value, Result = x.Element("result").Value }).FirstOrDefault();

                Result.Result = Details.Result;
                Result.Action = Details.Action;


                IEnumerable<XElement> xmlclients = (from x in mydoc.Descendants("ticket")
                                                    select x);
                if (Result.Result == "success")
                {
                    var Details2 = (from x in mydoc.Elements("whmcsapi")
                                    select new { totalresults = x.Element("totalresults").Value, startnumber = x.Element("startnumber").Value, numreturned = x.Element("numreturned").Value }).FirstOrDefault();
                    Result.TotalResults = Convert.ToInt32(Details2.totalresults);
                    Result.StartNumber = Convert.ToInt32(Details2.startnumber);
                    Result.NumReturned = Convert.ToInt32(Details2.numreturned);

                    foreach (XElement x in xmlclients)
                    {
                        Ticket tck = new Ticket();

                        tck.Id = x.Element("id").Value;
                        tck.Tid = x.Element("tid").Value;
                        tck.Deptid = x.Element("deptid").Value;
                        tck.Userid = x.Element("userid").Value;
                        tck.Name = x.Element("name").Value;
                        tck.Email = x.Element("email").Value;
                        tck.Cc = x.Element("cc").Value;
                        tck.C = x.Element("c").Value;
                        tck.Date = x.Element("date").Value;
                        tck.Subject = x.Element("subject").Value;
                       // tck.Message = x.Element("message").Value;
                        tck.Status = x.Element("status").Value;
                        tck.Priority = x.Element("priority").Value;
                        tck.Admin = x.Element("admin").Value;
                        tck.Attachment = x.Element("attachment").Value;
                        tck.Lastreply = x.Element("lastreply").Value;
                        tck.Flag = x.Element("flag").Value;
                        tck.Service = x.Element("service").Value;

                        ticketDetailsList.Add(tck);
                    }
                }
                else
                {
                    Result.ErrorMessage = (from x in mydoc.Elements("whmcsapi")
                                           select x.Element("message").Value).FirstOrDefault();
                }
            }
            catch (Exception ex)
            {
                Result.Result = "error";
                Result.ErrorMessage = ex.Message.ToString();
            }

            Result.Ticket = ticketDetailsList;
            return Result;
        }

        public ReplyTicketRS ReplyTicket(int ticketid = 0, int clientid = 0, string email = "", string adminusername = "", string message = "", string status="")
        {
            // Instantiate the WebClient object
            WebClient WHMCSclient = new WebClient();

            // Prepare a Name/Value collection to hold the post values
            NameValueCollection form = new NameValueCollection();
            form.Add("accesskey", accesskey);
            form.Add("username", username);
            form.Add("password", password); // the password will still need encoding is MD5 is a requirement
            form.Add("action", "addticketreply"); // action performed by the API:Functions
            form.Add("responsetype", "xml");

            form.Add("ticketid", ticketid.ToString());
            form.Add("clientid", clientid.ToString());
            form.Add("email", email);
            form.Add("adminusername", adminusername);
            form.Add("message", message);
            form.Add("status", status);


            // Post the data and read the response
            Byte[] responseData = WHMCSclient.UploadValues(installurl, form);

            // Decode and display the response.
            string xmlstring = Encoding.ASCII.GetString(responseData);
            XDocument mydoc = XDocument.Parse(xmlstring);

            ReplyTicketRS  Result = new ReplyTicketRS();
          
            try
            {
                var Details = (from x in mydoc.Elements("whmcsapi")
                               select new { Action = x.Element("action").Value, Result = x.Element("result").Value }).FirstOrDefault();
                Result.Result = Details.Result;
                Result.Action = Details.Action;
              
            }
            catch (Exception ex)
            {
                Result.Result = "error";
                Result.ErrorMessage = ex.Message.ToString();
            }

            return Result;
        }

        #endregion

        #region Open Ticket

        public OpenTicketRS OpenTicket(OpenTicket ObjOpenTkt)
        {

            // Instantiate the WebClient object
            WebClient WHMCSclient = new WebClient();

            // Prepare a Name/Value collection to hold the post values
            NameValueCollection form = new NameValueCollection();
            form.Add("accesskey", accesskey);
            form.Add("username", username);
            form.Add("password", password); // the password will still need encoding is MD5 is a requirement
            form.Add("action", "openticket"); // action performed by the API:Functions
            form.Add("responsetype", "xml");
            if (ObjOpenTkt.Clientid != 0)
            {
                form.Add("clientid", ObjOpenTkt.Clientid.ToString());
            }
            if (ObjOpenTkt.Deptid != 0)
            {
                form.Add("deptid", ObjOpenTkt.Deptid.ToString());
            }
            if (ObjOpenTkt.Subject != "")
            {
                form.Add("subject", ObjOpenTkt.Subject);
            }
            if (ObjOpenTkt.Priority != "")
            {
                if (ObjOpenTkt.Priority.CompareTo("Low") == 0 || ObjOpenTkt.Priority.CompareTo("Medium") == 0 || ObjOpenTkt.Priority.CompareTo("High") == 0)
                {
                    form.Add("priority", ObjOpenTkt.Priority);
                }
            }

            form.Add("message", ObjOpenTkt.Message);

            // Post the data and read the response
            Byte[] responseData = WHMCSclient.UploadValues(installurl, form);

            // Decode and display the response.
            string xmlstring = Encoding.ASCII.GetString(responseData);
            XDocument mydoc = XDocument.Parse(xmlstring);

            OpenTicketRS Result = new OpenTicketRS();

            try
            {
                var Details = (from x in mydoc.Elements("whmcsapi")
                               select new { Action = x.Element("action").Value, Result = x.Element("result").Value }).FirstOrDefault();

                Result.Action = Details.Action;
                Result.Result = Details.Result;

            }
            catch (Exception ex)
            {
                Result.Result = "error";
                Result.ErrorMessage = ex.Message.ToString();
            }

            // Decode and display the response.
            return Result;
        }

    

        #endregion

        #region Create Invoice

        public CreateInvoice CreateInvoice(CreateInvoice ObjInvoice)
        {

            // Instantiate the WebClient object
            WebClient WHMCSclient = new WebClient();

            // Prepare a Name/Value collection to hold the post values
            NameValueCollection form = new NameValueCollection();
            form.Add("accesskey", accesskey);
            form.Add("username", username);
            form.Add("password", password); // the password will still need encoding is MD5 is a requirement
            form.Add("action", "createinvoice"); // action performed by the API:Functions
            form.Add("responsetype", "xml");


            form.Add("userid", ObjInvoice.Userid.ToString());
            form.Add("date", ObjInvoice.Date);
            form.Add("duedate", ObjInvoice.Duedate);
            form.Add("paymentmethod", ObjInvoice.Paymentmethod);
            form.Add("sendinvoice", ObjInvoice.Sendinvoice.ToString());

            for (int i = 0; i < ObjInvoice.Itemdescription.Count; i++)
            {
                form.Add("itemdescription[" + (i + 1) + "]", ObjInvoice.Itemdescription[i]);
            }

            for (int i = 0; i < ObjInvoice.Itemamount.Count; i++)
            {
                form.Add("itemamount[" + (i + 1) + "]", ObjInvoice.Itemamount[i]);
            }

            for (int i = 0; i < ObjInvoice.Itemtaxed.Count; i++)
            {
                form.Add("itemtaxed[" + (i + 1) + "]", ObjInvoice.Itemtaxed[i]);
            }

        
            // Post the data and read the response
            Byte[] responseData = WHMCSclient.UploadValues(installurl, form);

            string xmlstring = Encoding.ASCII.GetString(responseData);
            XDocument mydoc = XDocument.Parse(xmlstring);

            CreateInvoice Result = new CreateInvoice();

            try
            {
                var Details = (from x in mydoc.Elements("whmcsapi")
                               select new { Invoiceid = x.Element("invoiceid").Value, Result = x.Element("result").Value }).FirstOrDefault();
                Result.Result = Details.Result;
                Result.Invoiceid  = Details.Invoiceid ;

            }
            catch (Exception ex)
            {
                Result.Result = "error";
                Result.ErrorMessage = ex.Message.ToString();
            }

            return Result;
        }

        #endregion

        #region Get Orders

        public string GetOrdersXML(int id = 0, int userid = 0, string status = "", int limitstart = 0, int limitnum = 0)
        {

            // Instantiate the WebClient object
            WebClient WHMCSclient = new WebClient();

            // Prepare a Name/Value collection to hold the post values
            NameValueCollection form = new NameValueCollection();
            form.Add("accesskey", accesskey);
            form.Add("username", username);
            form.Add("password", password); // the password will still need encoding is MD5 is a requirement
            form.Add("action", "getorders"); // action performed by the API:Functions
            form.Add("responsetype", "xml");

            if (id != 0)
            {
                form.Add("id", id.ToString());
            }
            if (userid != 0)
            {
                form.Add("userid", userid.ToString());
            }
            if (status != "")
            {
                if (status.CompareTo("Pending") == 0 || status.CompareTo("Active") == 0 || status.CompareTo("Fraud") == 0 || status.CompareTo("Cancelled") == 0)
                {
                    form.Add("status", status);
                }
            }
            if (limitstart != 0)
            {
                form.Add("limitstart ", limitstart.ToString());
            }
            if (limitnum != 0)
            {
                form.Add("limitnum ", limitnum.ToString());
            }

            // Post the data and read the response
            Byte[] responseData = WHMCSclient.UploadValues(installurl, form);

            // Decode and display the response.
            return Encoding.ASCII.GetString(responseData);
        }

        public GetOrdersRS GetOrders(int id = 0, int userid = 0, string status = "", int limitstart = 0, int limitnum = 0)
        {
            // Instantiate the WebClient object

            WebClient WHMCSclient = new WebClient();
            // Prepare a Name/Value collection to hold the post values
            NameValueCollection form = new NameValueCollection();
            form.Add("accesskey", accesskey);
            form.Add("username", username);
            form.Add("password", password); // the password will still need encoding is MD5 is a requirement
            form.Add("action", "getorders"); // action performed by the API:Functions
            form.Add("responsetype", "xml");

            if (id != 0)
            {
                form.Add("id", id.ToString());
            }
            if (userid != 0)
            {
                form.Add("userid", userid.ToString());
            }
            if (status != "")
            {
                if (status.CompareTo("Pending") == 0 || status.CompareTo("Active") == 0 || status.CompareTo("Fraud") == 0 || status.CompareTo("Cancelled") == 0)
                {
                    form.Add("status", status);
                }
            }
            if (limitstart != 0)
            {
                form.Add("limitstart ", limitstart.ToString());
            }
            if (limitnum != 0)
            {
                form.Add("limitnum ", limitnum.ToString());
            }

            // Post the data and read the response
            Byte[] responseData = WHMCSclient.UploadValues(installurl, form);

            // Decode and display the response.
            string xmlstring = Encoding.ASCII.GetString(responseData);
            XDocument mydoc = XDocument.Parse(xmlstring);

            GetOrdersRS Result = new GetOrdersRS();
            List<Orders> OrdersList = new List<Orders>();
            Orders ord = null;

            try
            {
                var Details = (from x in mydoc.Elements("orders")
                               select new { Action = x.Element("action").Value, Result = x.Element("result").Value }).FirstOrDefault();

                Result.Result = Details.Result;
                Result.Action = Details.Action;


                IEnumerable<XElement> xmlclients = (from x in mydoc.Descendants("orders")
                                                    select x);
                if (Result.Result == "success")
                {
                    var Details2 = (from x in mydoc.Elements("whmcsapi")
                                    select new { totalresults = x.Element("totalresults").Value, startnumber = x.Element("startnumber").Value, numreturned = x.Element("numreturned").Value }).FirstOrDefault();
                    Result.TotalResults = Convert.ToInt32(Details2.totalresults);
                    Result.StartNumber = Convert.ToInt32(Details2.startnumber);
                    Result.NumReturned = Convert.ToInt32(Details2.numreturned);

                    foreach (XElement x in xmlclients)
                    {
                        ord = new Orders();
                        ord.Id = Int64.Parse(x.Element("id").Value);
                        ord.Ordernum = x.Element("ordernum").Value;
                        ord.Userid = Int64.Parse(x.Element("userid").Value);
                        ord.Contactid = x.Element("contactid").Value;
                        ord.Date = DateTime.Parse(x.Element("date").Value);
                        ord.Nameservers = x.Element("nameservers").Value;
                        ord.Transfersecret = x.Element("transfersecret").Value;
                        ord.Promocode = x.Element("promocode").Value;
                        ord.Promotype = x.Element("promotype").Value;
                        ord.Promovalue = x.Element("promovalue").Value;
                        ord.Amount = Decimal.Parse(x.Element("amount").Value);
                        ord.Paymentmethodiveri = x.Element("paymentmethodiveri").Value;
                        ord.Invoiceid = Int64.Parse(x.Element("invoiceid").Value);
                        ord.Status = Boolean.Parse(x.Element("status").Value);
                        ord.Ipaddress = x.Element("ipaddress").Value;
                        ord.Fraudmodule = x.Element("fraudmodule").Value;
                        ord.Fraudoutput = x.Element("fraudoutput").Value;
                        ord.Notes = x.Element("notes").Value;
                        ord.Paymentmethodname = x.Element("paymentmethodname").Value;
                        ord.Paymentstatus = x.Element("paymentstatus").Value;
                        ord.NameA = x.Element("nameA").Value;
                    }
                }
                else
                {
                    Result.ErrorMessage = (from x in mydoc.Elements("whmcsapi")
                                           select x.Element("message").Value).FirstOrDefault();
                }
            }
            catch (Exception ex)
            {
                Result.Result = "error";
                Result.ErrorMessage = ex.Message.ToString();
            }

            Result.Orders = OrdersList;
            return Result;
        }

        #endregion

        #region Get Products

        public string GetProductsXML(int pid = 0, int gid = 0, string module = "")
        {

            // Instantiate the WebClient object
            WebClient WHMCSclient = new WebClient();

            // Prepare a Name/Value collection to hold the post values
            NameValueCollection form = new NameValueCollection();
            form.Add("accesskey", accesskey);
            form.Add("username", username);
            form.Add("password", password); // the password will still need encoding is MD5 is a requirement
            form.Add("action", "getproducts"); // action performed by the API:Functions
            form.Add("responsetype", "xml");

            if (pid != 0)
            {
                form.Add("pid", pid.ToString());
            }
            if (gid != 0)
            {
                form.Add("userid", gid.ToString());
            }
            if (module != "")
            {
                form.Add("module", module);
            }

            // Post the data and read the response
            Byte[] responseData = WHMCSclient.UploadValues(installurl, form);

            // Decode and display the response.
            return Encoding.ASCII.GetString(responseData);
        }

        public GetProductsRS GetProducts(int pid = 0, int gid = 0, string module = "")
        {
            // Instantiate the WebClient object

            WebClient WHMCSclient = new WebClient();
            // Prepare a Name/Value collection to hold the post values
            NameValueCollection form = new NameValueCollection();
            form.Add("accesskey", accesskey);
            form.Add("username", username);
            form.Add("password", password); // the password will still need encoding is MD5 is a requirement
            form.Add("action", "getproducts"); // action performed by the API:Functions
            form.Add("responsetype", "xml");

            if (pid != 0)
            {
                form.Add("pid", pid.ToString());
            }
            if (gid != 0)
            {
                form.Add("userid", gid.ToString());
            }
            if (module != "")
            {
                form.Add("module", module);
            }


            // Post the data and read the response
            Byte[] responseData = WHMCSclient.UploadValues(installurl, form);

            // Decode and display the response.
            string xmlstring = Encoding.ASCII.GetString(responseData);
            XDocument mydoc = XDocument.Parse(xmlstring);

            GetProductsRS Result = new GetProductsRS();
            List<Products> ProductList = new List<Products>();
            Products prd = null;

            try
            {
                var Details = (from x in mydoc.Elements("products")
                               select new { Action = x.Element("action").Value, Result = x.Element("result").Value }).FirstOrDefault();

                Result.Result = Details.Result;
                Result.Action = Details.Action;


                IEnumerable<XElement> xmlclients = (from x in mydoc.Descendants("product")
                                                    select x);
                if (Result.Result == "success")
                {
                    var Details2 = (from x in mydoc.Elements("whmcsapi")
                                    select new { totalresults = x.Element("totalresults").Value, startnumber = x.Element("startnumber").Value, numreturned = x.Element("numreturned").Value }).FirstOrDefault();
                    Result.TotalResults = Convert.ToInt32(Details2.totalresults);
                    Result.StartNumber = Convert.ToInt32(Details2.startnumber);
                    Result.NumReturned = Convert.ToInt32(Details2.numreturned);

                    foreach (XElement x in xmlclients)
                    {
                        prd = new Products();
                        prd.Pid = Int64.Parse(x.Element("pid").Value);
                        prd.Gid = Int64.Parse(x.Element("gid").Value);
                        prd.Type = x.Element("gype").Value;
                        prd.Name = x.Element("name").Value;
                        prd.Description = x.Element("description").Value;
                        prd.Module = x.Element("module").Value;
                        prd.Paytype = x.Element("paytype").Value;
                    }
                }
                else
                {
                    Result.ErrorMessage = (from x in mydoc.Elements("whmcsapi")
                                           select x.Element("message").Value).FirstOrDefault();
                }
            }
            catch (Exception ex)
            {
                Result.Result = "error";
                Result.ErrorMessage = ex.Message.ToString();
            }

            Result.Products = ProductList;
            return Result;
        }

        #endregion

        #region Add Order

        public string AddOrder(Order ObjOrder)
        {

            // Instantiate the WebClient object
            WebClient WHMCSclient = new WebClient();

            // Prepare a Name/Value collection to hold the post values
            NameValueCollection form = new NameValueCollection();
            form.Add("accesskey", accesskey);
            form.Add("username", username);
            form.Add("password", password); // the password will still need encoding is MD5 is a requirement
            form.Add("action", "addorder"); // action performed by the API:Functions
            form.Add("responsetype", "xml");
            form.Add("clientid", ObjOrder.Clientid.ToString());

            for (int i = 0; i < ObjOrder.Pid.Count; i++)
            {
                form.Add("pid[" + i + "]", ObjOrder.Pid[i]);
            }
            for (int i = 0; i < ObjOrder.Domain.Count; i++)
            {
                form.Add("domain[" + i + "]", ObjOrder.Domain[i]);
            }
            for (int i = 0; i < ObjOrder.Billingcycle.Count; i++)
            {
                form.Add("billingcycle[" + i + "]", ObjOrder.Billingcycle[i]);
            }

            form.Add("addons", ObjOrder.Addons);
            form.Add("customfields", ObjOrder.Customfields);
            form.Add("domaintype", ObjOrder.Domaintype);
            form.Add("regperiod", ObjOrder.Regperiod);
            form.Add("paymentmethod", ObjOrder.Paymentmethod);

            // Post the data and read the response
            Byte[] responseData = WHMCSclient.UploadValues(installurl, form);

            // Decode and display the response.
            return Encoding.ASCII.GetString(responseData);
        }

        #endregion

        #region Upgrade Products

        public string AddOrder(UpgradeProductRS ObjUpgradeProduct)
        {

            // Instantiate the WebClient object
            WebClient WHMCSclient = new WebClient();

            // Prepare a Name/Value collection to hold the post values
            NameValueCollection form = new NameValueCollection();
            form.Add("accesskey", accesskey);
            form.Add("username", username);
            form.Add("password", password); // the password will still need encoding is MD5 is a requirement
            form.Add("action", "upgradeproduct"); // action performed by the API:Functions
            form.Add("responsetype", "xml");

            form.Add("clientid", ObjUpgradeProduct.Clientid.ToString());
            form.Add("serviceid", ObjUpgradeProduct.Serviceid.ToString());
            form.Add("type", ObjUpgradeProduct.Type.ToString());
            form.Add("newproductid", ObjUpgradeProduct.Newproductid.ToString());
            form.Add("newproductbillingcycle", ObjUpgradeProduct.Newproductbillingcycle.ToString());

            for (int i = 0; i < ObjUpgradeProduct.Configoptions.Count; i++)
            {
                form.Add("configoptions[" + i + "]", ObjUpgradeProduct.Configoptions[i]);
            }

            form.Add("paymentmethod", ObjUpgradeProduct.Paymentmethod.ToString());
            form.Add("ordernotes", ObjUpgradeProduct.Ordernotes.ToString());
            form.Add("calconly", ObjUpgradeProduct.Calconly.ToString());


            // Post the data and read the response
            Byte[] responseData = WHMCSclient.UploadValues(installurl, form);

            // Decode and display the response.
            return Encoding.ASCII.GetString(responseData);
        }


        #endregion

        #region Get Client Products

        public string GetClientProductsXML(int clientid = 0, int serviceid = 0, string domain = "" ,int pid  = 0)
        {

            // Instantiate the WebClient object
            WebClient WHMCSclient = new WebClient();

            // Prepare a Name/Value collection to hold the post values
            NameValueCollection form = new NameValueCollection();
            form.Add("accesskey", accesskey);
            form.Add("username", username);
            form.Add("password", password); // the password will still need encoding is MD5 is a requirement
            form.Add("action", "getclientsproducts"); // action performed by the API:Functions
            form.Add("responsetype", "xml");

            if (clientid != 0)
            {
                form.Add("clientid", clientid.ToString());
            }
            if (serviceid != 0)
            {
                form.Add("serviceid", serviceid.ToString());
            }
            if (domain != "")
            {
                form.Add("domain", domain);
            }
            if (pid != 0)
            {
                form.Add("pid", pid.ToString());
            }

            // Post the data and read the response
            Byte[] responseData = WHMCSclient.UploadValues(installurl, form);

            // Decode and display the response.
            return Encoding.ASCII.GetString(responseData);
        }

        public GetClientsProductsRS GetClientProducts(int clientid = 0, int serviceid = 0, string domain = "", int pid = 0)
        {
            // Instantiate the WebClient object

            WebClient WHMCSclient = new WebClient();
            // Prepare a Name/Value collection to hold the post values
            NameValueCollection form = new NameValueCollection();
            form.Add("accesskey", accesskey);
            form.Add("username", username);
            form.Add("password", password); // the password will still need encoding is MD5 is a requirement
            form.Add("action", "getclientsproducts"); // action performed by the API:Functions
            form.Add("responsetype", "xml");

            if (clientid != 0)
            {
                form.Add("clientid", clientid.ToString());
            }
            if (serviceid != 0)
            {
                form.Add("serviceid", serviceid.ToString());
            }
            if (domain != "")
            {
                form.Add("domain", domain);
            }
            if (pid != 0)
            {
                form.Add("pid", pid.ToString());
            }


            // Post the data and read the response
            Byte[] responseData = WHMCSclient.UploadValues(installurl, form);

            // Decode and display the response.
            string xmlstring = Encoding.ASCII.GetString(responseData);
            XDocument mydoc = XDocument.Parse(xmlstring);

            GetClientsProductsRS Result = new GetClientsProductsRS();
            List<ClientProduct> ProductList = new List<ClientProduct>();
            ClientProduct prd = null;
            CustomField custFld = null;
            Configuration config = null;

            try
            {
                var Details = (from x in mydoc.Elements("whmcsapi")
                               select new { Action = x.Element("action").Value, Result = x.Element("result").Value }).FirstOrDefault();

                Result.Result = Details.Result;
                Result.Action = Details.Action;


                IEnumerable<XElement> xmlclients = (from x in mydoc.Descendants("product")
                                                    select x);
                if (Result.Result == "success")
                {
                    var Details2 = (from x in mydoc.Elements("whmcsapi")
                                    select new { totalresults = x.Element("totalresults").Value, startnumber = x.Element("startnumber").Value, numreturned = x.Element("numreturned").Value }).FirstOrDefault();
                    Result.TotalResults = Convert.ToInt32(Details2.totalresults);
                    Result.StartNumber = Convert.ToInt32(Details2.startnumber);
                    Result.NumReturned = Convert.ToInt32(Details2.numreturned);

                    foreach (XElement x in xmlclients)
                    {
                        prd = new ClientProduct();

                        prd.Id = x.Element("id").Value;
                        prd.OrderId = x.Element("orderid").Value; ;
                        prd.Pid = x.Element("pid").Value; ;
                        prd.RegDate = x.Element("regdate").Value; ;
                        prd.Name = x.Element("name").Value; ;
                        prd.Groupname = x.Element("groupname").Value; ;
                        prd.Domain = x.Element("domain").Value; ;
                        prd.Dedicatedip = x.Element("dedicatedip").Value; ;
                        prd.Serverid = x.Element("serverid").Value; ;
                        prd.Servername = x.Element("servername").Value; ;
                        prd.Firstpaymentamount = x.Element("firstpaymentamount").Value; ;
                        prd.Recurringamount = x.Element("recurringamount").Value; ;
                        prd.Paymentmethodpaypal = x.Element("paymentmethod").Value; ;
                        prd.PaymentmethodnameCredit = x.Element("paymentmethodname").Value; ;
                        prd.Billingcycle = x.Element("billingcycle").Value; ;
                        prd.Nextduedate = x.Element("nextduedate").Value;
                        prd.Status = x.Element("status").Value; ;
                        prd.Username = x.Element("username").Value; ;
                        prd.Password = x.Element("password").Value; ;
                        prd.Subscriptionid = x.Element("subscriptionid").Value; ;
                        prd.Promoid = x.Element("promoid").Value; ;
                        prd.Overideautosuspend = x.Element("overideautosuspend").Value; ;
                        prd.Overidesuspenduntil = x.Element("overidesuspenduntil").Value; ;
                        prd.Ns1 = x.Element("ns1").Value; 
                        prd.Ns2 = x.Element("ns2").Value; 
                        prd.Assignedips = x.Element("assignedips").Value; ;
                        prd.Notes = x.Element("notes").Value;
                        prd.Diskusage = x.Element("diskusage").Value;
                        prd.Disklimit = x.Element("disklimit").Value;
                        prd.Bwusage = x.Element("bwusage").Value;
                        prd.Bwlimit = x.Element("bwlimit").Value;
                        prd.Lastupdate = x.Element("lastupdate").Value;
                        prd.Customfields = new List<CustomField>();
                        prd.Configuration = new List<Configuration>();

                        IEnumerable<XElement> custf = (from c in mydoc.Descendants("customfield")
                                                            select c);
                        foreach (XElement c in custf)
                        {
                            custFld = new CustomField();
                            custFld.Name = c.Element("name").Value;
                            custFld.Value = c.Element("value").Value;
                            prd.Customfields.Add(custFld);
                        }
                        IEnumerable<XElement> cnfg = (from co in mydoc.Descendants("configoption")
                                                            select co);
                        foreach (XElement co in cnfg)
                        {
                            config = new Configuration();
                            config.Option = co.Element("option").Value;
                            config.Value = co.Element("value").Value;
                            prd.Configuration.Add(config);
                        }
                        ProductList.Add(prd);
                    }
                }
                else
                {
                    Result.ErrorMessage = (from x in mydoc.Elements("whmcsapi")
                                           select x.Element("message").Value).FirstOrDefault();
                }
            }
            catch (Exception ex)
            {
                Result.Result = "error";
                Result.ErrorMessage = ex.Message.ToString();
            }

            Result.ClientProduct = ProductList;
            return Result;
        }

        #endregion

        #region Update Client Product

        public string UpdateClientProduct(UpdateProduct ObjProduct)
        {

            // Instantiate the WebClient object
            WebClient WHMCSclient = new WebClient();

            // Prepare a Name/Value collection to hold the post values
            NameValueCollection form = new NameValueCollection();
            form.Add("accesskey", accesskey);
            form.Add("username", username);
            form.Add("password", password); // the password will still need encoding is MD5 is a requirement
            form.Add("action", "updateclientproduct"); // action performed by the API:Functions
            form.Add("responsetype", "xml");

            form.Add("serviceid", ObjProduct.Serviceid);
            form.Add("pid", ObjProduct.Pid);
            form.Add("serverid", ObjProduct.Serverid);
            form.Add("regdate", ObjProduct.Regdate);
            form.Add("nextduedate", ObjProduct.Nextduedate);
            form.Add("domain", ObjProduct.Domain);
            form.Add("firstpaymentamount", ObjProduct.Firstpaymentamount);
            form.Add("recurringamount", ObjProduct.Recurringamount);
            form.Add("billingcycle", ObjProduct.Billingcycle);
            form.Add("paymentmethod", ObjProduct.Paymentmethod);
            form.Add("status", ObjProduct.Status);
            form.Add("serviceusername", ObjProduct.Serviceusername);
            form.Add("servicepassword", ObjProduct.Servicepassword);
            form.Add("subscriptionid", ObjProduct.Subscriptionid);
            form.Add("promoid", ObjProduct.Promoid);
            form.Add("overideautosuspend", ObjProduct.Overideautosuspend);
            form.Add("overidesuspenduntil", ObjProduct.Overidesuspenduntil);
            form.Add("ns1", ObjProduct.Ns1);
            form.Add("ns2", ObjProduct.Ns2);
            form.Add("dedicatedip", ObjProduct.Dedicatedip);
            form.Add("assignedips", ObjProduct.Assignedips);
            form.Add("notes", ObjProduct.Notes);
            form.Add("autorecalc", ObjProduct.Autorecalc);
            form.Add("customfields", ObjProduct.Customfields);


            // Post the data and read the response
            Byte[] responseData = WHMCSclient.UploadValues(installurl, form);

            // Decode and display the response.
            return Encoding.ASCII.GetString(responseData);
        }

        #endregion

    }
}
